昨天我們將障礙加入到背景場景中,並能隨機在範圍中生成。
不幸的是今天將角色加入時,發現碰撞似乎會無法正常運作,所以先重新調整我們的背景場景做一些小改動,做錯誤中學習也是一個難得的經驗QQ。
建立一個新場景作為我們替代的背景並儲存到 Scenes
中。
在場景中建立一個 Node2D
節點作為根節點命名為 Background
,接著在這個根節點下建立兩個 Sprite2D
節點作為我們循環的背景圖節點並重新命名及在屬性面板中設定 Texture
圖片。
# 結構如下:
|--Background (Node2D)
| |--DynamicBG2 (Sprite2D)
| |--DynamicBG1 (Sprite2D)
接著我們複製之前的背景程式做一些修改後使用
Sprite2D
並更新初始化的物件及調整第二背景移動方法。var background1:Sprite2D
var background2:Sprite2D
func _ready():
# ...
background1 = $DynamicBG1
background2 = $DynamicBG2
# ...
# 改成使用 set_position
background2.set_position(Vector2(0, -viewpoint_height))
scroll_background
# 更新輸入參數型別
func scroll_background(bg:Sprite2D):
# 更新獲取位置方法
var offset = bg.position
offset.y += speed * get_process_delta_time()
if offset.y >= viewpoint_height:
bg.set_texture(randomBackground[randi()%randomBackground.size()])
offset.y = offset.y - viewpoint_height*2
# set new randf pos for obstacles
for obstacle in backgrounds_to_obstacles[bg]:
obstacle.position = get_randf_pos()
# 更新設置位置方法
bg.set_position(offset)
Transform
更改 position
。新增暴露角色起始位置方法,更改角色腳本
@export var start_position :Vector2 = Vector2(360, 1300)
func _ready():
# ...
player.position = start_position
# ...
建立遊戲的主要場景
Scenes
下。Node
Instantiate child scene
將我們的背景場景和角色場景放到根節點下# 結構如下:
|-- Main (Node)
| |--Background (Scene)
| |--Player (Scene)
完整檔案
extends Node2D
@export var randomBackground:Array
@export var speed: float = 500
# obstacles
@export var obstacles:Array
var backgrounds_to_obstacles:Dictionary
var background1:Sprite2D
var background2:Sprite2D
var viewpoint_width:float
var viewpoint_height:float
# Called when the node enters the scene tree for the first time.
func _ready():
viewpoint_width = get_viewport().size.x
viewpoint_height = get_viewport().size.y
background1 = $DynamicBG1
background2 = $DynamicBG2
backgrounds_to_obstacles = {
background1: [],
background2: []
}
# create reused obstacles
for bg in backgrounds_to_obstacles.keys():
for obstacle in obstacles:
var obstacle_instantiate = obstacle.instantiate()
obstacle_instantiate.position = Vector2(0, -viewpoint_height*2)
bg.add_child(obstacle_instantiate)
backgrounds_to_obstacles[bg].append(obstacle_instantiate)
background2.set_position(Vector2(0, -viewpoint_height))
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
scroll_background(background1)
scroll_background(background2)
func scroll_background(bg:Sprite2D):
var offset = bg.position
offset.y += speed * get_process_delta_time()
if offset.y >= viewpoint_height:
bg.set_texture(randomBackground[randi()%randomBackground.size()])
offset.y = offset.y - viewpoint_height*2
# set new randf pos for obstacles
for obstacle in backgrounds_to_obstacles[bg]:
obstacle.position = get_randf_pos()
bg.set_position(offset)
func get_randf_pos():
return Vector2(randf_range(-viewpoint_width/2, viewpoint_width/2), randf_range(-viewpoint_height/2, viewpoint_height/2))
process
前的程式碼,非完整)extends CharacterBody2D
# shader
var anime_sprite = AnimatedSprite2D
# CharacterBody2D
var direction:Vector2
var dragged:bool = false
var oriPos: Vector2
var player: CharacterBody2D
var player_anime: AnimatedSprite2D
# MovementUI
var movement_ui: Node2D
# Collision Handling
@export var slow_speed:float = 1
@export var base_speed:float = 5
# start position
@export var start_position :Vector2 = Vector2(360, 1300)
var speed:float = base_speed
var invincible_timer:Timer
var slow_timer:Timer
var stop_timer:Timer
const DEFAULT = "DEFAULT"
var state:String = DEFAULT
# Called when the node enters the scene tree for the first time.
func _ready():
anime_sprite = $AnimatedSprite2D
movement_ui = $"../MovementUI"
movement_ui.visible = false
player = $"."
player_anime = player.get_node("AnimatedSprite2D")
# init player postition
player.position = start_position
invincible_timer = $"../InvincibleTimer"
invincible_timer.timeout.connect(_on_invincible_timeout)
slow_timer = $"../SlowTimer"
slow_timer.timeout.connect(_on_slow_timeout)
stop_timer = $"../StopTimer"
stop_timer.timeout.connect(_on_stop_timeout)
# ...
# 其他方法未更動略過
:)